
Imports cmplib01
Imports system.Drawing
Imports System.Drawing.Drawing2D

'// this form allows an author to see what items are connected to each other. It allows the deleting of an entire chain of items


Public Class frmPrerequisites

    Private ptrCGD As CampaignerGameData
    Private HotPoints As New Collection   '// this is the items that are shown on the client, clicking near them will navigate to the object.
    Private drawLines As New Collection

    Public Property GameData() As CampaignerGameData
        Get
            Return ptrCGD
        End Get
        Set(ByVal value As CampaignerGameData)
            ptrCGD = value
            '// populate
            obdObjects.campaignerGameData = ptrCGD
            '// force a new listing
            obdObjects.ListItems()
        End Set
    End Property

    Private Sub obdObjects_ItemSelected(ByRef obj As Object, ByRef objectType As cmplib01.CampaignerObjectType_cot) Handles obdObjects.ItemSelected
        '// this will start the draw process.
        If Not obj Is Nothing Then DrawForItem(obj)
    End Sub


    Private Sub DrawForItem(ByVal obj As Object)
        '// here's how this works...
        '// on the left are items that this guy uses
        '// in the "center" is this guy
        '// on the right are items that use THIS guy
        If TypeOf obj Is UnitType Then
            DrawForItem(DirectCast(obj, UnitType))
        ElseIf TypeOf obj Is ObjectiveType Then
            DrawForItem(DirectCast(obj, ObjectiveType))
        ElseIf TypeOf obj Is RuleType Then
            DrawForItem(DirectCast(obj, RuleType))
        ElseIf TypeOf obj Is ResourceType Then
            DrawForItem(DirectCast(obj, ResourceType))
        End If
    End Sub

    Private Sub DrawForItem(ByVal unie As UnitType)
        Try
            '// unit types are used by nothing (well, battlegroups, but nothing in the builder)
            '// unit types can use resources... so that's all there is to that. Resources.

            '// find the center.
            Dim center As New Point(picClient.Width / 3, 37)
            Dim drawSpot As New Point(5, 25)

            Dim g As Graphics = picClient.CreateGraphics
            HotPoints = New Collection
            drawLines = New Collection

            '// start drawing the things that this guy uses (left side)
            Dim key As String
            For Each rut As RuleType In unie.GCRules
                For Each key In ptrCGD.RuleTypes_g.HT.Keys
                    Dim checkRule As RuleType = ptrCGD.RuleTypes_g.Item(key)
                    If rut.RuleName = checkRule.RuleName Then
                        '// draw a line from one object to the next
                        drawLines.Add(New line(center, drawSpot, Color.Blue))

                        '// yup
                        Dim hottie As New HotPoint
                        hottie.obj = checkRule
                        hottie.name = checkRule.RuleName
                        hottie.location = drawSpot
                        hottie.forecolor = Color.Black
                        hottie.backcolor = Color.AliceBlue
                        HotPoints.Add(hottie)

                        '// increase y
                        drawSpot = New Point(drawSpot.X, drawSpot.Y + 24)
                    End If
                Next
            Next

            Dim theHot As New HotPoint
            With theHot
                .backcolor = Color.Yellow
                .forecolor = Color.Black
                .location = center
                .name = unie.Name
                .obj = unie
            End With

            HotPoints.Add(theHot)

            picClient.Invalidate()

        Catch ex As Exception
            HandleException("frmPrerequisites.Draw", ex)
        End Try
    End Sub

    Private Sub DrawForItem(ByVal inst As ObjectiveType)
        Try
            '// installations can use resources and rules, so both of those will have to be listed.
            '// installations can be USED by deployed installations, so lets check that. It goes on the right.
            Dim center As New Point(picClient.Width / 3, 25)
            Dim drawspot As New Point(5, 37)

            Dim g As Graphics = picClient.CreateGraphics
            HotPoints = New Collection
            drawLines = New Collection

            '// left side stuff (code reuse anyone?)
            Dim key As String
            For Each rut As RuleType In inst.GCRules
                For Each key In ptrCGD.RuleTypes_g.HT.Keys
                    Dim checkrule As RuleType = ptrCGD.RuleTypes_g.Item(key)
                    If rut.RuleName = checkrule.RuleName Then
                        '// draw a line from one object to the next
                        drawLines.Add(New line(center, drawspot, Color.Blue))

                        '// yup
                        Dim hottie As New HotPoint
                        hottie.obj = checkrule
                        hottie.name = checkrule.RuleName
                        hottie.location = drawspot
                        hottie.forecolor = Color.Black
                        hottie.backcolor = Color.AliceBlue
                        HotPoints.Add(hottie)

                        '// increase y
                        drawspot = New Point(drawspot.X, drawspot.Y + 24)
                    End If
                Next
            Next

            '// resources
            For Each key In inst.ObjectiveResources.HT.Keys
                Dim res As Resource = inst.ObjectiveResources.Item(key)
                For Each skey As String In ptrCGD.ResourceTypes_g.HT.Keys
                    Dim rest As ResourceType = ptrCGD.ResourceTypes_g.Item(skey)
                    If res.ResourceName = rest.ResourceName Then
                        drawLines.Add(New line(center, drawspot, Color.Blue))

                        Dim hottie As New HotPoint
                        hottie.obj = res
                        hottie.name = res.ResourceName
                        hottie.location = drawspot
                        hottie.forecolor = Color.Black
                        hottie.backcolor = Color.BlanchedAlmond
                        HotPoints.Add(hottie)
                        drawspot = New Point(drawspot.X, drawspot.Y + 24)
                    End If
                Next
            Next

            drawspot = New Point(picClient.Width - picClient.Width / 4, 37)

            '// deployed (right side)
            Dim mem As ChitMember
            For Each mem In ptrCGD.Chits
                If mem.UnitType = GroundChitClass_cgd.Objective Then
                    Dim depInst As InstallationChit = DirectCast(mem, InstallationChit)
                    If depInst.ptrInstallation.Equals(inst) Then

                        drawLines.Add(New line(center, drawspot, Color.Blue))
                        Dim hottie As New HotPoint
                        hottie.obj = mem
                        hottie.location = drawspot
                        hottie.name = mem.Name
                        hottie.forecolor = Color.Black
                        hottie.backcolor = Color.LightSeaGreen
                        HotPoints.Add(hottie)
                        drawspot = New Point(drawspot.X, drawspot.Y + 24)
                    End If
                End If
            Next

            Dim theHot As New HotPoint
            With theHot
                .backcolor = Color.Yellow
                .forecolor = Color.Black
                .location = center
                .name = inst.Name
                .obj = inst
            End With

            HotPoints.Add(theHot)
            picClient.Invalidate()


        Catch ex As Exception
            HandleException("frmPrerequisites.Draw", ex)
        End Try
    End Sub

    Private Sub DrawForItem(ByVal res As ResourceType)
        Try
            '// resources use nothing else, but can be used by rules and installations, so nothing will be on the right.
            Dim center As New Point(picClient.Width / 3, 25)
            Dim drawspot As New Point(picClient.Width - picClient.Width / 4, 37)

            Dim g As Graphics
            HotPoints = New Collection
            drawLines = New Collection

            '// right side!
            Dim key As String
            '// resources
            For Each key In ptrCGD.RuleTypes_g.HT.Keys
                Dim rut As RuleType = ptrCGD.RuleTypes_g.Item(key)
                If TypeOf rut Is ResourceConsumingRuleType Then
                    Dim resrul As ResourceConsumingRuleType = rut
                    For Each co As ResourceCost In resrul.Costs
                        If co.ResourceTypeName = res.ResourceName Then
                            drawLines.Add(New line(center, drawspot, Color.Blue))

                            Dim hottie As New HotPoint
                            hottie.obj = rut
                            hottie.location = drawspot
                            hottie.name = rut.RuleName
                            hottie.forecolor = Color.Black
                            hottie.backcolor = Color.LightSeaGreen
                            HotPoints.Add(hottie)
                            drawspot = New Point(drawspot.X, drawspot.Y + 24)
                        End If
                    Next
                End If
            Next

            '// ok, now installation types
            For Each obj As ObjectiveType In ptrCGD.ObjectiveTypes
                For Each key In obj.ObjectiveResources.HT.Keys
                    Dim rez As Resource = obj.ObjectiveResources.Item(key)
                    If rez.ResourceName = res.ResourceName Then
                        drawLines.Add(New line(center, drawspot, Color.Blue))

                        Dim hottie As New HotPoint
                        hottie.obj = obj
                        hottie.name = obj.Name
                        hottie.location = drawspot
                        hottie.forecolor = Color.Black
                        hottie.backcolor = Color.LightSeaGreen
                        HotPoints.Add(hottie)
                        drawspot = New Point(drawspot.X, drawspot.Y + 24)
                    End If
                Next
            Next

            '// victory conditions
            For Each key In ptrCGD.Faction_g.HT.Keys
                Dim fact As Faction = ptrCGD.Faction_g.Item(key)
                For Each vc As IVictoryCondition In fact.FactionVictoryConditions
                    If vc.VCType = VictoryConditionClass_cgd.Resource Then
                        Dim resvict As ResourceVictoryCondition = vc
                        If resvict.TargetResourceType.ResourceName = res.ResourceName Then
                            drawLines.Add(New line(center, drawspot, Color.Blue))

                            Dim hottie As New HotPoint
                            hottie.obj = vc
                            hottie.location = drawspot
                            hottie.name = vc.VictoryConditionName
                            hottie.forecolor = Color.Black
                            hottie.backcolor = Color.LightSkyBlue
                            HotPoints.Add(hottie)
                            drawspot = New Point(drawspot.X, drawspot.Y + 24)

                        End If
                    End If
                Next
            Next

            Dim theHot As New HotPoint
            With theHot
                .backcolor = Color.Yellow
                .forecolor = Color.Black
                .location = center
                .name = res.ResourceName
                .obj = res
            End With

            HotPoints.Add(theHot)

            picClient.Invalidate()

        Catch ex As Exception
            HandleException("frmPrerequisites.Draw", ex)
        End Try
    End Sub

    Private Sub DrawForItem(ByVal rul As RuleType)
        Try

            Dim center As New Point(picClient.Width / 3, 25)
            Dim drawspot As New Point(5, 37)
            Dim g As Graphics = picClient.CreateGraphics
            HotPoints = New Collection
            drawLines = New Collection

            '// a rule can use resources, but nothing else, so only resources will appear on the left.
            If TypeOf rul Is ResourceConsumingRuleType Then
                Dim resrul As ResourceConsumingRuleType = rul

                For Each resco As ResourceCost In resrul.Costs
                    For Each key As String In ptrCGD.ResourceTypes_g.HT.Keys
                        Dim res As ResourceType = ptrCGD.ResourceTypes_g.Item(key)
                        If resco.ResourceTypeName = res.ResourceName Then
                            drawLines.Add(New line(center, drawspot, Color.Blue))
                            Dim hottie As New HotPoint
                            hottie.obj = res
                            hottie.name = res.ResourceName
                            hottie.forecolor = Color.Black
                            hottie.backcolor = Color.AliceBlue
                            hottie.location = drawspot
                            HotPoints.Add(hottie)
                            drawspot = New Point(drawspot.X, drawspot.Y + 24)
                        End If

                    Next
                Next
            End If

            '// a rule can be used by installations and unit types, so they go on the right.
            '// installations
            For Each obj As ObjectiveType In ptrCGD.ObjectiveTypes
                For Each rut As RuleType In obj.GCRules
                    If rut.RuleName = rul.RuleName Then

                        drawLines.Add(New line(center, drawspot, Color.Blue))
                        Dim hottie As New HotPoint
                        hottie.obj = obj
                        hottie.name = obj.Name
                        hottie.backcolor = Color.LightSeaGreen
                        hottie.forecolor = Color.Black
                        hottie.location = drawspot
                        HotPoints.Add(hottie)
                        drawspot = New Point(drawspot.X, drawspot.Y + 24)
                    End If
                Next
            Next

            For Each un As UnitType In ptrCGD.UnitTypes
                For Each rut As RuleType In un.GCRules
                    If rut.RuleName = rul.RuleName Then
                        drawLines.Add(New line(center, drawspot, Color.Blue))
                        Dim hottie As New HotPoint
                        hottie.obj = un
                        hottie.name = un.Name
                        hottie.backcolor = Color.AntiqueWhite
                        hottie.forecolor = Color.Black
                        hottie.location = drawspot
                        HotPoints.Add(hottie)
                        drawspot = New Point(drawspot.X, drawspot.Y + 24)

                    End If
                Next
            Next

            Dim theHot As New HotPoint
            With theHot
                .backcolor = Color.Yellow
                .forecolor = Color.Black
                .location = center
                .name = rul.RuleName
                .obj = rul
            End With

            HotPoints.Add(theHot)

            picClient.Invalidate()

        Catch ex As Exception
            HandleException("frmPrerequisites.Draw", ex)
        End Try
    End Sub

    Private Sub DrawItem(ByRef g As Graphics, ByVal text As String, ByVal location As Point, ByVal forecolor As Color, ByVal backcolor As Color, ByRef obj As Object)
        Try
            Dim pth As New GraphicsPath()
            Dim pnt As New PointF(location.X, location.Y)

            pth.AddString(text, System.Drawing.FontFamily.GenericSerif, System.Drawing.FontStyle.Regular, 12, location, System.Drawing.StringFormat.GenericDefault)

            Dim bounds As RectangleF = pth.GetBounds
            Dim boundsBrush As New SolidBrush(backcolor)
            ' increase the size of the box by 1 pixel all the way around
            bounds.X -= 1
            bounds.Y -= 1
            bounds.Width += 3
            bounds.Height += 3

            ' do the markbox. The markbox is a square around the actual position of the label, its basically an arrow.
            Dim markBoxSolid As New RectangleF(bounds.X - 3, bounds.Y - 3, 6, 6)
            Dim markBrush As New SolidBrush(Color.Red)
            Dim markBoxBounds As New Rectangle(markBoxSolid.X, markBoxSolid.Y, markBoxSolid.Width, markBoxSolid.Height)
            g.FillRectangle(markBrush, markBoxSolid)
            g.DrawRectangle(Pens.Black, markBoxBounds)
            markBrush.Dispose()

            Dim boundsBox As New Rectangle(bounds.X, bounds.Y, bounds.Width, bounds.Height)
            g.FillRectangle(boundsBrush, bounds)
            g.DrawRectangle(Pens.Black, boundsBox)
            boundsBrush.Dispose()

            Dim textBrush As New SolidBrush(forecolor)
            'br.Color = lab.foreColor
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias
            g.FillPath(textBrush, pth)
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default
            textBrush.Dispose()
        Catch ex As Exception
            HandleException("frmPrerequisites.Draw", ex)
        End Try
    End Sub

    Private Sub DrawItem(ByRef g As Graphics, ByVal hot As HotPoint)
        DrawItem(g, hot.name, hot.location, hot.forecolor, hot.backcolor, hot.obj)
    End Sub


    Private Sub btnOK_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOK.Click
        Me.Hide()
    End Sub

    Private Sub JumpToHotPoint(ByVal location As Point)
        '// sets the object to selected in the obddefined as well.
        Try

        Catch ex As Exception
            HandleException("frmPrerequisites.Jump", ex)
        End Try
    End Sub

    Private Sub picClient_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles picClient.Paint
        Dim g As Graphics = e.Graphics
        g.Clear(picClient.BackColor)

        '// draw all lines, then all items in the hotpoints collection
        For Each lin As line In drawLines
            g.DrawLine(New Pen(lin.lineColor), lin.endLocation, lin.startLocation)
        Next

        '// draw all hotitems
        For Each hot As HotPoint In HotPoints
            DrawItem(g, hot)
        Next

    End Sub
End Class


Friend Class HotPoint
    Public location As Point
    Public reg As Region  '// this is so it can be clicked
    Public obj As Object
    Public name As String '// in case we need it.
    Public forecolor As Color
    Public backcolor As Color
End Class

Friend Class line
    Public startLocation As Point
    Public endLocation As Point
    Public lineColor As Color

    Public Sub New(ByVal linestart As Point, ByVal lineend As Point, ByVal linecol As Color)
        startLocation = linestart
        endLocation = lineend
        lineColor = linecol
    End Sub

End Class